#!/bin/sh
#
# ------------------------------------------------------
# Squirrel - a script for finding and caching batch output.
#
# How to use squirrel:  Squirrel should be started in your
#   batch file after changing to the appropriate directory
#   but before running the job itself.  Use the following command:
#
#   squirrel <unitree_directory> &
#
#   where <unitree_directory is the path in Unitree where data is
#   to be stored.  For example: "squirrel amr/bigrun/output"
#   would store the data in Unitree directory "amr/bigrun/output".
#   Note that this directory must be created before running squirrel.
#
#   The "&" at the end insures that squirrel runs in the background
#   (it will use a negligible amount of cpu time).
#
#   The script itself will search for files of the form "*.hierarchy".
#   It then moves all the files associated with this output into a
#   separate directory, tars up that directory and send it to
#   Unitree.  For example, if there is an output RedshiftOutput0000.hierarchy
#   then it moves all RedshiftOutput0000.* files into the directory
#   RedshiftOutput0000.dir, tars this up as RedshiftOutput0000.tar
#   and sends it to Unitree.
#
#   If restarting from an output, squirrel should be told not to
#   cache the restart output file.  This is done by adding the
#   argument "-x <exempt_file>", where <exempt_file> is the base name
#   of the output.  For example, if restarting from "RedshiftOutput0002",
#   then use "squirrel -x RedshiftOutput0002 ...".
#
#   Finally, after the run finishes and write the last output, give
#   squirrel a little time to finish up with the following commands
#   (in your batch script):
#
#   sleep 400
#   touch squirrel_stop
#   sleep 100
#
#   (Note that squirrel doesn't star auxillary enzo files such
#    as "OutputLevelInformation.out", etc. so these must be copied
#    output explicitely at the end of the script.)
#
#   Squirrel generates a log file called "squirrel.log".
#
#   Since squirrel and mascmd each take up an extra processes, you
#     will have to request two extra threads in the batch job
#     specification file (e.g. for enzo running 16 processes, ask for 18)
#
# ------------------------------------------------------
#
# usage: squirrel [-x exempt_file] unitree_directory
#
#   where unitree_directory is the path in Unitree where data is stored
#         exempt_file is a base name that should be exempted from
#              squirrel's searches (i.e. the restart data file).
#
#   e.g.   squirrel -x RedshiftOutput0004 amr/this_directory
#
# ------------------------------------------------------
#
# The following line sets the Unitree commands that are executed
#   before sending the data.

UNITREE_COMMAND='bin, quote site setfam cobalt, '

# ------------------------------------------------------

#  decode arguments

EXEMPT=''

while [ $# -gt 1 ]
do 
  case ${1} in
    -x) EXEMPT=${2}
        shift 2
        ;; 
    *) echo "unknown option ${1}"
       exit 1
       ;;
  esac
done

if [ $# -ne 1 ]; then
   echo 'usage: squirrel [-x exempt] unitree_directory'
   exit 1
fi

UNITREE_DIRECTORY=$1

#  Open log file

LOGFILE=squirrel.log
#/bin/rm $LOGFILE
echo `date`': squirrel alive' >> $LOGFILE

if [ "${EXEMPT}.hierarchy" != '.hierarchy' ]; then
  echo `date`": exempting ${EXEMPT}" >> $LOGFILE
fi

#  Set directory to work in

DIRECTORY=`pwd`
echo `date`': working directory='${DIRECTORY} >> $LOGFILE

# ------------------------------------------------------
#  Do this loop forever, or until someone kills us or puts a file
#    called squirrel_stop in the working directory

while [ ! -f ${DIRECTORY}/squirrel_stop ]
do

#  Look for nuts:
#     check for non-zero length *.hierarchy files

  FILES=*.hierarchy
  for HIERARCHY_FILE in ${FILES}
  do
    if [ -f ${HIERARCHY_FILE} -a ${HIERARCHY_FILE} != "${EXEMPT}.hierarchy" ]; then

#     Found a nut!

      echo `date`': found nut: '${HIERARCHY_FILE} >> $LOGFILE
      BASE_NAME=`echo ${HIERARCHY_FILE} | sed 's/\.hierarchy//'`

#     Is it zero length or still being modified?

      touch SQUIRREL_TEMP
      sleep 100
      if [ ! -s ${HIERARCHY_FILE} ]; then
        echo `date`": ${HIERARCHY_FILE} zero length (will try later)" >> $LOGFILE
      elif `newer ${HIERARCHY_FILE} SQUIRREL_TEMP`; then
        echo `date`": ${HIERARCHY_FILE} still green (will try later)" >> $LOGFILE
      else

#       make directory

	NEW_DIR=${BASE_NAME}.dir
        if [ -d ${NEW_DIR} ]; then
           echo `date`': warning! ${NEW_DIR} already exists!' >> $LOGFILE
           echo `date`':          tarring anyway (as is)' >> $LOGFILE
        else
           mkdir ${NEW_DIR}
        fi

#       move files in directory (done this way to get around sgi's
#           argument limit).  Good up to 100000 grids.

        echo `date`": moving files to ${NEW_DIR}" >> $LOGFILE
        NUMBERS=`echo 0 1 2 3 4 5 6 7 8 9`
        NUMBERS2=`echo 1 2 3 4 5 6 7 8 9`
        for i in $NUMBERS
        do
          for j in $NUMBERS
          do
            /bin/mv ${BASE_NAME}.grid${i}${j}?? ${NEW_DIR} 2> /dev/null
            for k in $NUMBERS2
            do
              /bin/mv ${BASE_NAME}.grid${k}${i}${j}?? ${NEW_DIR} 2> /dev/null
            done
          done
        done
        /bin/mv ${BASE_NAME} ${NEW_DIR} 2> /dev/null
        /bin/mv ${BASE_NAME}.[bh]* ${NEW_DIR} 2> /dev/null
        /bin/mv ${BASE_NAME}.radiation ${NEW_DIR} 2> /dev/null
	/bin/mv ${BASE_NAME}.* ${NEW_DIR}

#       tar file

        echo `date`": tarring ${NEW_DIR}" >> $LOGFILE
        TAR_FILE=${BASE_NAME}.tar
        tar -cf ${TAR_FILE} ${NEW_DIR} >> $LOGFILE

#       hide nut (send to unitree)

        echo `date`": hiding nut (Unitree dir=${UNITREE_DIRECTORY})" >> $LOGFILE
        msscmd cd ${UNITREE_DIRECTORY}, ${UNITREE_COMMAND} put ${TAR_FILE} >> $LOGFILE
        /bin/rm -r ${TAR_FILE} 2> /dev/null

#       should delete directory, but only if tar and msscmd successful

        echo `date`": done hiding nut" >> $LOGFILE
        
      fi

#     remove temp file

      /bin/rm SQUIRREL_TEMP 2> /dev/null

    fi
  done

# nap time

  sleep 5

done

echo `date`': squirrel stopping by request' >> $LOGFILE

exit 0
